/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package unilearn.bo;

import java.util.ArrayList;
import java.util.List;
import unilearn.dao.GroupMemberDAO;
import unilearn.dao.PersonDAO;
import unilearn.dao.PersonRoleDAO;
import unilearn.dao.RoleDAO;
import unilearn.dao.StudentGroupDAO;
import unilearn.vo.Assignment;
import unilearn.vo.GroupMember;
import unilearn.vo.Person;
import unilearn.vo.PersonRole;
import unilearn.vo.Role;
import unilearn.vo.StudentGroup;

/**
 *
 * @author Ming
 */
public class StudentGroupManagement {

    private StudentGroupDAO studentGroupDAO;
    private GroupMemberDAO groupMemberDAO;
    private PersonDAO personDAO;
    private RoleDAO roleDAO;
    private PersonRoleDAO personRoleDAO;

    public StudentGroupManagement() {
        studentGroupDAO = null;
        groupMemberDAO = null;
        roleDAO = null;
        personRoleDAO = null;
    }

    public StudentGroupManagement(StudentGroupDAO studentGroupDAO, GroupMemberDAO groupMemberDAO, RoleDAO roleDAO, PersonRoleDAO personRoleDAO) {
        this();
        this.studentGroupDAO = studentGroupDAO;
        this.groupMemberDAO = groupMemberDAO;
        this.roleDAO = roleDAO;
        this.personRoleDAO = personRoleDAO;
    }

    public void setGroupMemberDAO(GroupMemberDAO groupMemberDAO) {
        this.groupMemberDAO = groupMemberDAO;
    }

    public void setPersonRoleDAO(PersonRoleDAO personRoleDAO) {
        this.personRoleDAO = personRoleDAO;
    }

    public void setPersonDAO(PersonDAO personDAO) {
        this.personDAO = personDAO;
    }

    public void setRoleDAO(RoleDAO roleDAO) {
        this.roleDAO = roleDAO;
    }

    public void setStudentGroupDAO(StudentGroupDAO studentGroupDAO) {
        this.studentGroupDAO = studentGroupDAO;
    }

    private List<StudentGroup> getAllStudentGroups() throws Exception {
        return studentGroupDAO.getAll();
    }

    public List<StudentGroup> getStudentGroups(Assignment assignment, Person person) throws Exception {
        PersonRole pr = new PersonRole();
        pr.setPersonId(person.getId());
        List<PersonRole> prs = personRoleDAO.find(pr);
        if ((prs == null) || (prs.isEmpty())) {
            throw new Exception("This person(ID: " + person.getId() + ") has not any role.");
        }
        pr = prs.get(0);

        Role role = roleDAO.get(pr.getRoleId());
        if (role == null) {
            throw new Exception("Could not find this role(ID: " + pr.getRoleId() + ")");
        }

        return this.getStudentGroups(assignment, person, role);
    }

    public List<StudentGroup> getStudentGroups(Assignment assignment, Person person, Role role) throws Exception {
        if (role.getName().equals("lecturer")) {
            return getAllStudentGroups();
        } else if (role.getName().equals("student")) {
            StudentGroup group = new StudentGroup();
            group.setSubjectCode(assignment.getSubjectCode());
            group.setAssignmentId(assignment.getId());
            List<StudentGroup> groups = studentGroupDAO.find(group);
            if ((groups == null) || (groups.isEmpty())) {
                throw new Exception("Could not find any StudentGroup.");
            }

            group = null;
            GroupMember gm = new GroupMember();
            gm.setPersonId(person.getId());
            for (StudentGroup sg : groups) {
                gm.setGroupId(sg.getId());
                List<GroupMember> gms = groupMemberDAO.find(gm);
                if ((gms != null) && (!gms.isEmpty())) {
                    group = sg;
                    break;
                }
            }

            groups.clear();
            groups.add(group);
            return groups;
        } else {
            throw new Exception("you can not get any student group.");
        }
    }

    public List<Person> getGroupMembers(StudentGroup studentGroup) throws Exception {
        GroupMember searchGm = new GroupMember();
        searchGm.setGroupId(studentGroup.getId());
        List<GroupMember> gms = groupMemberDAO.find(searchGm);
        if ((gms == null) || (gms.isEmpty())) {
            return null;
        }

        List<Person> members = new ArrayList();
        for (GroupMember gm : gms) {
            Person p = personDAO.get(gm.getPersonId());
            if (p != null) {
                members.add(p);
            }
        }

        return members;
    }

    public StudentGroup createStudentGroup(Assignment assignment, List<Person> persons) throws Exception {
        Role role = new Role();
        role.setName("student");
        List<Role> rs = roleDAO.find(role);

        if ((rs == null) || (rs.isEmpty())) {
            throw new Exception("Could not find role(student).");
        }

        role = rs.get(0);

        for (Person p : persons) {
            PersonRole pr = new PersonRole();
            pr.setPersonId(p.getId());
            pr.setRoleId(role.getId());
            List<PersonRole> prs = personRoleDAO.find(pr);
            if ((prs == null) || (prs.isEmpty())) {
                throw new Exception("This person(ID: " + p.getId() + ") is not student.");
            }
        }

        StudentGroup group = new StudentGroup();
        group.setSubjectCode(assignment.getSubjectCode());
        group.setAssignmentId(assignment.getId());

        group = studentGroupDAO.insert(group);

        this.updateGroupMembers(group, persons);

        return group;
    }

    public List<Person> updateGroupMembers(StudentGroup studentGroup, List<Person> persons) throws Exception {
        GroupMember searchGm = new GroupMember();
        searchGm.setGroupId(studentGroup.getId());
        List<GroupMember> gms = groupMemberDAO.find(searchGm);

        if ((gms != null) || (!gms.isEmpty())) {
            for (GroupMember gm : gms) {
                groupMemberDAO.delete(gm);
            }
        }

        List<GroupMember> members = new ArrayList();
        for (Person p : persons) {
            GroupMember gm = new GroupMember();
            gm.setGroupId(studentGroup.getId());
            gm.setPersonId(p.getId());
            members.add(groupMemberDAO.insert(gm));
        }

        return this.getGroupMembers(studentGroup);
    }

    public void removeStudentGroup(StudentGroup studentGroup) throws Exception {
        GroupMember member = new GroupMember();
        member.setGroupId(studentGroup.getId());
        List<GroupMember> gms = groupMemberDAO.find(member);
        if ((gms != null) || (!gms.isEmpty())) {
            for (GroupMember gm : gms) {
                groupMemberDAO.delete(gm);
            }
        }

        studentGroupDAO.delete(studentGroup);
    }
}
